package com.xuecheng.media;

import com.alibaba.nacos.common.utils.MD5Utils;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.Test;

import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

public class BigFileTesy {

    /**
     * @return void
     * @description 本地文件分片
     * @author: woldier
     * @date: 2023/3/11 8:50
     */
    @Test
    public void shading() throws IOException {
        /*
         * 1.指定本地文件路径，分片大小，分片后文件存储位置
         * 2.根据文件大小与分片大小得到分片数目，创建对应文件
         * 3.分片写入
         * */
        //本地源文件
        File source = new File("D:\\Joker\\Desktop\\2025.mp4");
        FileInputStream inputStream = new FileInputStream(source);
        //分片保存的文件夹
        File chunkDir = new File("D:\\Joker\\Desktop\\chunk");
        if (chunkDir.mkdirs()) {
            System.out.println("目录创建成功：" + chunkDir.getAbsolutePath());
        } else {
            System.out.println("目录创建失败或目录已存在：" + chunkDir.getAbsolutePath());
        }
        //分片大小
        Long chunkSize = 1024 * 1024 * 5L; // 分片大小，1MB
        //分片数目 source.length()：获取源文件的大小（字节数）
        int shardingNum = (int) Math.ceil((source.length() * 1.0 / chunkSize)); // 向上取整 返回的是double
        //缓冲区
        byte[] b = new byte[1024]; // 1KB 缓冲区
        for (int i = 0; i < shardingNum; i++) {
            //创建分片文件
            File shadedFile = new File(chunkDir, String.valueOf(i));
            //创建分片文件输出流 // 为每个分片文件创建一个 FileOutputStream，用于写入数据。
            FileOutputStream shaded = new FileOutputStream(shadedFile);
            int len = -1;
            while ((len = inputStream.read(b)) != -1) { // 按字节读取到缓冲区 b 中
                shaded.write(b, 0, len);
                if (shadedFile.length() >= chunkSize) break;  //当该分片达到分片大小时跳出
            }
            shaded.close();
        }
        inputStream.close();
    }

    /**
     * @description 分片文件聚合
     *
     * @return void
     * @author: woldier
     * @date: 2023/3/11 10:36
     */
    @Test
    public void merging() throws IOException {
        /*
         * 1.从分片文件夹中获取所有文件
         * 2.写入
         * */
        //分片文件目录
        File sourceDir = new File("D:\\Joker\\Desktop\\chunk");
        //目标文件
        File target = new File("D:\\Joker\\Desktop\\2025—merge.mp4");
        //目标文件输出流
        FileOutputStream fileOutputStream = new FileOutputStream(target);
        String[] list = sourceDir.list();
        assert list != null;
        /*文件排序*/
        List<String> fileListSorted = Arrays.asList(list).stream().sorted(Comparator.comparing(Integer::valueOf)).collect(Collectors.toList());
        byte[] b = new byte[1024];
        fileListSorted.forEach(
                e -> {
                    try {
                        FileInputStream inputStream = new FileInputStream(new File(sourceDir, e));
                        int len = -1;
                        while((len=inputStream.read(b)) != -1){
                            fileOutputStream.write(b,0,len);
                        }
                        inputStream.close();
                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                }
        );
        fileOutputStream.close();
        // 合并后文件的校验
        FileInputStream fileInputStream_merge = new FileInputStream(target);
        File source = new File("D:\\Joker\\Desktop\\2025.mp4");
        FileInputStream fileInputStream_source = new FileInputStream(source);
        String md5_merge = DigestUtils.md5Hex(fileInputStream_merge);
        String md5_source = DigestUtils.md5Hex(fileInputStream_source);
        if (md5_merge.equals(md5_source)){
            System.out.println("校验成功");
        }

    }
}
